/**
 * This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be
 * useful, but WITHOUT ANY WARRANTY. See the GNU General Public License for more details. Copyright (C) 2011 CellObject.net
 */
package net.cellobject.sqlitexmlbrowser;

import net.cellobject.sqlitexmlbrowser.shared.PrivateAccessor;
import net.cellobject.sqlitexmlbrowser.sqlitebrowser.util.SqliteUtil;
import net.cellobject.sqlitexmlbrowser.sqlitebrowser.view.SqliteBrowserView;
import net.cellobject.sqlitexmlbrowser.xmlopener.XmlOpener;
import net.cellobject.sqlitexmlbrowser.xmlopener.XmlUtil;

import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeItem;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.IPartListener;
import org.eclipse.ui.IStartup;
import org.eclipse.ui.IViewPart;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;
import com.android.ddmlib.FileListingService.FileEntry;
import com.android.ddmuilib.explorer.DeviceExplorer;
import com.android.ide.eclipse.ddms.CommonAction;
import com.android.ide.eclipse.ddms.views.FileExplorerView;

public class SQLiteXMLBrowserPluginStartup implements IStartup {
	private final String FILEEXPLORERVIEW_ID = FileExplorerView.ID;

	public static CommonAction devToolsFileOpenerAction;

	private static boolean actionAdded = false;

	@Override
	public void earlyStartup() {
		Display.getDefault().asyncExec(new Runnable() {
			@Override
			public void run() {
				final IWorkbenchWindow workbenchWindow = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
				if (workbenchWindow != null) {
					workbenchWindow.getActivePage().addPartListener(new IPartListener() {
						@Override
						public void partActivated(final IWorkbenchPart part) {
							createsqlitebrowserAction(part);
						}

						@Override
						public void partBroughtToTop(final IWorkbenchPart part) {
							// Pass
						}

						@Override
						public void partClosed(final IWorkbenchPart part) {
							final IViewPart view = (IViewPart)part.getAdapter(IViewPart.class);
							if ( (view != null) && (view.getViewSite().getId().indexOf(FILEEXPLORERVIEW_ID) > -1)) {
								actionAdded = false;
							}
						}

						@Override
						public void partDeactivated(final IWorkbenchPart part) {
							// Pass
						}

						@Override
						public void partOpened(final IWorkbenchPart part) {
							// Pass
						}
					});
				}
			}
		});
	}

	private void createsqlitebrowserAction(final IWorkbenchPart part) {
		final IViewPart view = (IViewPart)part.getAdapter(IViewPart.class);
		if ( (view != null) && (view.getViewSite().getId().indexOf(FILEEXPLORERVIEW_ID) > -1)) {
			if (!actionAdded) {
				actionAdded = true; // don't add action more than once
				createsqlitebrowserActionGui(view);
				// Listen to mTreeViewer SelectionChanged
				final DeviceExplorer mExplorer = (DeviceExplorer)PrivateAccessor.getPrivateField(view, "mExplorer");
				final TreeViewer mTreeViewer = (TreeViewer)PrivateAccessor.getPrivateField(mExplorer, "mTreeViewer");
				mTreeViewer.addSelectionChangedListener(new ISelectionChangedListener() {
					@Override
					public void selectionChanged(final SelectionChangedEvent event) {
						final ISelection selection = event.getSelection();
						if (selection.isEmpty()) {
							devToolsFileOpenerAction.setEnabled(false);
							return;
						}
						if (selection instanceof IStructuredSelection) {
							final IStructuredSelection structuredSelection = (IStructuredSelection)selection;
							final Object element = structuredSelection.getFirstElement();
							if (element == null) {
								return;
							}
							if (element instanceof FileEntry) {
								// It is SQLite database file
								if ( (structuredSelection.size() == 1) && SqliteUtil.isSqliteDbFile((FileEntry)element)) {
									devToolsFileOpenerAction.setImageDescriptor(SQLiteXMLBrowserPlugin.getImageDescriptor("icons/sqlitebrowser.gif"));
									devToolsFileOpenerAction.setToolTipText("Open File in SQLite Browser...");
									devToolsFileOpenerAction.setEnabled(true);
								} else if ( (structuredSelection.size() == 1) && XmlUtil.isXmlFile((FileEntry)element)) {
									devToolsFileOpenerAction.setImageDescriptor(SQLiteXMLBrowserPlugin.getImageDescriptor("icons/xml.png"));
									devToolsFileOpenerAction.setToolTipText("Open XML File...");
									devToolsFileOpenerAction.setEnabled(true);
								} else {
									devToolsFileOpenerAction.setEnabled(false);
								}
							}
						}
					}
				});
			}
		}
	}

	private void createsqlitebrowserActionGui(final IViewPart fileExplorerView) {
		final DeviceExplorer mExplorer = (DeviceExplorer)PrivateAccessor.getPrivateField(fileExplorerView, "mExplorer");
		final Tree mTree = (Tree)PrivateAccessor.getPrivateField(mExplorer, "mTree");
		final IActionBars actionBars = fileExplorerView.getViewSite().getActionBars();
		final IMenuManager menuManager = actionBars.getMenuManager();
		final IToolBarManager toolBarManager = actionBars.getToolBarManager();
		// Define action
		devToolsFileOpenerAction = new CommonAction("Open File...") {
			@Override
			public void run() {
				final TreeItem[] items = mTree.getSelection();
				if (items.length == 1) {
					final FileEntry singleEntry = (FileEntry)items[0].getData();
					final IWorkbenchPage activePage = fileExplorerView.getViewSite().getPage();
					if (SqliteUtil.isSqliteDbFile(singleEntry)) {
						// Open sqlitebrowserView
						try {
							Display.getDefault().syncExec(new Runnable() {
								@Override
								public void run() {
									try {
										final SqliteBrowserView sqliteBrowserView = (SqliteBrowserView)activePage.findView(SqliteBrowserView.ID);
										if (sqliteBrowserView != null) {
											activePage.hideView(sqliteBrowserView);
										}
										SqliteBrowserView.mExplorer = mExplorer;
										SqliteBrowserView.fileEntry = singleEntry;
										// Disable button to prevent multiple
										// clicks, and enable again after
										// finishing opening file.
										devToolsFileOpenerAction.setEnabled(false);
										activePage.showView(SqliteBrowserView.ID); // Open
										// the
										// view
										// with
										// new
										// db
										// file
									} catch (final Exception e) {
										e.printStackTrace();
									}
								}
							});
						} catch (final Exception e) {
							e.printStackTrace();
						}
					} else if (XmlUtil.isXmlFile(singleEntry)) {
						// Open XML file
						try {
							Display.getDefault().syncExec(new Runnable() {
								@Override
								public void run() {
									try {
										// Disable button to prevent multiple
										// clicks, and enable again after
										// finishing opening file.
										devToolsFileOpenerAction.setEnabled(false);
										XmlOpener.openXmlFile(activePage, mExplorer, singleEntry);
									} catch (final Exception e) {
										e.printStackTrace();
									}
								}
							});
						} catch (final Exception e) {
							e.printStackTrace();
						}
					}
				}
			}
		};
		devToolsFileOpenerAction.setId("sqlitebrowserAction");
		devToolsFileOpenerAction.setImageDescriptor(SQLiteXMLBrowserPlugin.getImageDescriptor("icons/sqlitebrowser.gif"));
		devToolsFileOpenerAction.setToolTipText("Open File...");
		devToolsFileOpenerAction.setEnabled(false);
		// Add action to menu bar
		menuManager.add(new Separator());
		menuManager.add(devToolsFileOpenerAction);
		menuManager.update(true);
		// Add action to tool bar
		toolBarManager.add(new Separator());
		toolBarManager.add(devToolsFileOpenerAction);
		toolBarManager.update(true);
	}
}
